﻿/****************************** Module Header ******************************\
* Module Name:	Program.cs
* Project:		CSPInvokeDll
* Copyright (c) Microsoft Corporation.
* 
* Platform Invocation Services (PInvoke) in .NET allows managed code to call  
* unmanaged functions that are implemented and exported in unmanaged DLLs.  
* This sample shows you what you need to do to be able to call the exported 
* functions in the unmanaged DLLs like CppDllExport.dll, msvcrt.dll, from C#.
* 
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
* All other rights reserved.
* 
* History:
* * 1/21/2009 11:04 PM Jialiang Ge Created
\***************************************************************************/

#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion

namespace CSPInvokeDll
{
    /// <summary>
    /// Program
    /// </summary>
    class Program
    {
        /// <summary>
        /// Main
        /// </summary>
        static void Main(string[] args)
        {

            // P/Invoke a method exported with extern "C" declspec(dllexport)
            {
                int result = NativeMethod.Add(2, 3);
                Console.WriteLine("CppDllExport!Add(2, 3) => {0}", result);
            }

            // P/Invoke a method exported with a def file
            {
                string result;
                NativeMethod.HelloWorld(out result);
                Console.WriteLine("CppDllExport!HelloWorld => {0}", result);
            }

            // P/Invoke a method that requires callback as one of the args.
            {
                NativeMethod.CompareCallback cmpFunc = 
                    new NativeMethod.CompareCallback(CompareInts);
                int result = NativeMethod.Max(2, 3, cmpFunc);
                // Make sure the lifetime of the delegate instance covers the 
                // lifetime of the unmanaged code; otherwise, the delegate 
                // will not be available after it is garbage-collected.
                GC.KeepAlive(cmpFunc);  

                Console.WriteLine("CppDllExport!Max(2, 3) => {0}", result);
            }

            // P/Invoke an STDCALL API, MessageBox, in user32.dll
            {
                NativeMethod.MessageBoxResult result =
                    NativeMethod.MessageBox(IntPtr.Zero, "test", "test",
                    NativeMethod.MessageBoxOptions.OkCancel);
                Console.WriteLine("User32!MessageBox => {0}", result);
            }

            // P/Invoke a CDECL API, printf, in msvcrt.dll
            {
                Console.Write("msvcrt!printf => ");
                NativeMethod.printf("%s!%s\n", "msvcrt", "printf");
            }

        } // Main(args)

        static int CompareInts(int a, int b)
        {
            if (a > b) return 1;
            if (a < b) return -1;
            return 0;
        }

    } // class Program
} // namespace CSPInvokeDll
